﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Acms.Exceptions;

namespace ClimateChangeChampionsData
{
    public partial class School
    {
        public static IQueryable<School> GetAll(DataContext context, string sortExpression)
        {

            var data = from user in context.Users
                       join schoolName in context.UserCustomProperties on user.Id equals schoolName.UserId
                       join schoolType in context.UserCustomProperties on user.Id equals schoolType.UserId
                       join schoolTel in context.UserCustomProperties on user.Id equals schoolTel.UserId
                       join secondaryContact in context.UserCustomProperties on user.Id equals secondaryContact.UserId
                       where schoolName.Name == "School Name"
                            && schoolType.Name == "School Type"
                            && schoolTel.Name == "School Tel"
                            && secondaryContact.Name == "Secondary Contact Name"
                       select new{user, schoolName, schoolType, schoolTel, secondaryContact};

            /*if(!string.IsNullOrEmpty(sortExpression))
            {


                foreach (string key in sorts.Keys)
                {
                    if(key.Equals("Address1", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (sorts[key])
                        {
                            data = data.OrderByDescending(x => x.user.Address1);
                        }
                        else
                        {
                            data = data.OrderBy(x => x.user.Address1);
                        }
                    }
                    else if (key.Equals("Address2", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (sorts[key])
                        {
                            data = data.OrderByDescending(x => x.user.Address2);
                        }
                        else
                        {
                            data = data.OrderBy(x => x.user.Address2);
                        }
                    }
                    else if (key.Equals("County", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (sorts[key])
                        {
                            data = data.OrderByDescending(x => x.user.County);
                        }
                        else
                        {
                            data = data.OrderBy(x => x.user.County);
                        }
                    }
                    else if (key.Equals("Created", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (sorts[key])
                        {
                            data = data.OrderByDescending(x => x.user.Created);
                        }
                        else
                        {
                            data = data.OrderBy(x => x.user.Created);
                        }
                    }
                    else if (key.Equals("DateOfBirth", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (sorts[key])
                        {
                            data = data.OrderByDescending(x => x.user.DateOfBirth);
                        }
                        else
                        {
                            data = data.OrderBy(x => x.user.DateOfBirth);
                        }
                    }
                    else if (key.Equals("EmailAddress", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (sorts[key])
                        {
                            data = data.OrderByDescending(x => x.user.EmailAddress);
                        }
                        else
                        {
                            data = data.OrderBy(x => x.user.EmailAddress);
                        }
                    }
                    else if (key.Equals("FirstName", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (sorts[key])
                        {
                            data = data.OrderByDescending(x => x.user.FirstName);
                        }
                        else
                        {
                            data = data.OrderBy(x => x.user.FirstName);
                        }
                    }
                    else if (key.Equals("LastName", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (sorts[key])
                        {
                            data = data.OrderByDescending(x => x.user.LastName);
                        }
                        else
                        {
                            data = data.OrderBy(x => x.user.LastName);
                        }
                    }
                    else if (key.Equals("MobileTel", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (sorts[key])
                        {
                            data = data.OrderByDescending(x => x.user.MobileTel);
                        }
                        else
                        {
                            data = data.OrderBy(x => x.user.MobileTel);
                        }
                    }
                    else if (key.Equals("PostCode", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (sorts[key])
                        {
                            data = data.OrderByDescending(x => x.user.PostCode);
                        }
                        else
                        {
                            data = data.OrderBy(x => x.user.PostCode);
                        }
                    }
                    else if (key.Equals("SiteId", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (sorts[key])
                        {
                            data = data.OrderByDescending(x => x.user.SiteId);
                        }
                        else
                        {
                            data = data.OrderBy(x => x.user.SiteId);
                        }
                    }
                    else if (key.Equals("Town", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (sorts[key])
                        {
                            data = data.OrderByDescending(x => x.user.Town);
                        }
                        else
                        {
                            data = data.OrderBy(x => x.user.Town);
                        }
                    }
                    else if (key.Equals("UserName", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (sorts[key])
                        {
                            data = data.OrderByDescending(x => x.user.UserName);
                        }
                        else
                        {
                            data = data.OrderBy(x => x.user.UserName);
                        }
                    }
                    else if (key.Equals("SchoolName", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (sorts[key])
                        {
                            data = data.OrderByDescending(x => x.schoolName.Value);
                        }
                        else
                        {
                            data = data.OrderBy(x => x.user.LastName);
                        }
                    }
                    else if (key.Equals("schoolTel", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (sorts[key])
                        {
                            data = data.OrderByDescending(x => x.schoolTel.Value);
                        }
                        else
                        {
                            data = data.OrderBy(x => x.schoolTel.Value);
                        }
                    }
                    else if (key.Equals("schoolType", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (sorts[key])
                        {
                            data = data.OrderByDescending(x => x.schoolType.Value);
                        }
                        else
                        {
                            data = data.OrderBy(x => x.schoolType.Value);
                        }
                    }
                    else if (key.Equals("secondaryContact", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (sorts[key])
                        {
                            data = data.OrderByDescending(x => x.secondaryContact.Value);
                        }
                        else
                        {
                            data = data.OrderBy(x => x.secondaryContact.Value);
                        }
                    }
                }
            }*/
            

            return from d in data select new School(d.user, d.schoolName, d.schoolType, d.schoolTel, d.secondaryContact);

        }

        public School()
        {
            _User = new User();
            _SchoolName = new UserCustomProperty() { Name = "School Name" };
            _SchoolType = new UserCustomProperty() { Name = "School Type" };
            _SchoolTel = new UserCustomProperty() { Name = "School Tel" };
            _SecondaryContactName = new UserCustomProperty() { Name = "Secondary Contact Name" };
        }

        private School(User user, UserCustomProperty schoolName, UserCustomProperty schoolType, UserCustomProperty schoolTel, UserCustomProperty secondaryContactName)
        {
            _User = user;
            _SchoolName = schoolName;
            _SchoolType = schoolType;
            _SchoolTel = schoolTel;
            _SecondaryContactName = secondaryContactName;
        }

        public User _User;
        public UserCustomProperty _SchoolName;
        public UserCustomProperty _SchoolType;
        public UserCustomProperty _SchoolTel;
        public UserCustomProperty _SecondaryContactName;



        public string SchoolName 
        {
            get { return _SchoolName.Value; }
            set { _SchoolName.Value = value; }
        }

        public string SchoolType
        {
            get { return _SchoolType.Value; }
            set { _SchoolType.Value = value; }
        }

        public string SchoolTel
        {
            get { return _SchoolTel.Value; }
            set { _SchoolTel.Value = value; }
        }
        
        public string Address1
        {
            get { return _User.Address1; }
            set { _User.Address1 = value; }
        }

        public string Address2
        {
            get { return _User.Address2; }
            set { _User.Address2 = value; }
        }

        public string AddressTown
        {
            get { return _User.Town; }
            set { _User.Town = value; }
        }

        public string AddressCounty 
        {
            get { return _User.County; }
            set { _User.County = value; }
        }

        public string AddressPostCode
        {
            get { return _User.PostCode; }
            set { _User.PostCode = value; }
        }

        public string GetFullAddress(string spacer)
        {
            string internalSpacer = "|_|";
            StringBuilder tmp = new StringBuilder();
            tmp.Append(Address1);
            tmp.Append(internalSpacer);
            tmp.Append(Address2);
            tmp.Append(internalSpacer);
            tmp.Append(AddressTown);
            tmp.Append(internalSpacer);
            tmp.Append(AddressCounty);
            tmp.Append(internalSpacer);
            tmp.Append(AddressPostCode);
            string tmp2 = tmp.ToString();
            while (tmp2.IndexOf(string.Concat(internalSpacer, internalSpacer)) >= 0)
            {
                tmp2 = tmp2.Replace(string.Concat(internalSpacer, internalSpacer), internalSpacer);
            }
            if (tmp2.StartsWith(internalSpacer))
            {
                tmp2 = tmp2.Substring(internalSpacer.Length);
            }
            if (tmp2.EndsWith(internalSpacer))
            {
                tmp2 = tmp2.Substring(0, tmp2.Length - internalSpacer.Length);
            }
            return tmp2.Replace(internalSpacer, spacer);
        }

        public string FirstName
        {
            get { return _User.FirstName; }
            set { _User.LastName = value; }
        }
        
        public string LastName
        {
            get { return _User.LastName; }
            set { _User.LastName = value; }
        }

        public string DisplayName
        {
            get
            {
                return string.Concat(FirstName, " ", LastName).Trim();
            }
        }

        public string ContactEmail
        {
            get { return _User.EmailAddress; }
            set { _User.EmailAddress = value; }
        }

        public string ContactTel
        {
            get { return _User.MobileTel; }
            set { _User.MobileTel = value; }
        }

        public string SecondaryContactName
        {
            get { return _SecondaryContactName.Value; }
            set { _SecondaryContactName.Value = value; }
        }

        public DateTime Created 
        {
            get { return DateTime.SpecifyKind(_User.Created, DateTimeKind.Utc); }
            set { _User.Created = value.ToUniversalTime(); }
        }

        public string Username
        {
            get { return _User.UserName; }
            set { _User.UserName = value; }
        }

        /*public SchoolType Type
        {
            get { return (SchoolType)this.SchoolType;}
            set { this.SchoolType = (short)value; }
        }

        partial void OnValidate(System.Data.Linq.ChangeAction action)
        {
            DataContext context = new DataContext();
            ValidationException valExcep = new ValidationException();
            //check required fields
            if (string.IsNullOrEmpty(SchoolName))
            {
                valExcep.Add(new ValidationExceptionItem("School Name must be entered."));
            }

            if (SchoolType == 0)
            {
                valExcep.Add(new ValidationExceptionItem("School Type must be entered."));
            }

            if (string.IsNullOrEmpty(Address1))
            {
                valExcep.Add(new ValidationExceptionItem("School Address must be entered."));
            }

            if (string.IsNullOrEmpty(Town))
            {
                valExcep.Add(new ValidationExceptionItem("School Town must be entered."));
            }

            if (string.IsNullOrEmpty(PostCode))
            {
                valExcep.Add(new ValidationExceptionItem("School Post Code must be entered."));
            }
            else if (!ValidatePostCode(PostCode))
            {
                valExcep.Add(new ValidationExceptionItem("School Post Code is not valid."));
            }

            if (string.IsNullOrEmpty(SchoolTel))
            {
                valExcep.Add(new ValidationExceptionItem("School Telephone Number must be entered."));
            }

            if (string.IsNullOrEmpty(ContactFirstName) || string.IsNullOrEmpty(ContactLastName))
            {
                valExcep.Add(new ValidationExceptionItem("Contact Name must be entered."));
            }

            if (string.IsNullOrEmpty(ContactEmail))
            {
                valExcep.Add(new ValidationExceptionItem("Contact Email must be entered."));
            }
            else if (!ValidateEmail(ContactEmail))
            {
                valExcep.Add(new ValidationExceptionItem("Contact Email must be a valid email address."));
            }

            if (string.IsNullOrEmpty(Password))
            {
                valExcep.Add(new ValidationExceptionItem("Password must be entered."));
            }
            else if (!ValidatePassword(Password))
            {
                valExcep.Add(new ValidationExceptionItem("Password must be between 6 and 14 characters long and can only conatin alphanumeric characters."));
            }

            //check that this email address is unique for the school
            School tmp = School.GetByContactEmail(ContactEmail, context);
            if (tmp != null && tmp.Id != this.Id)
            {
                valExcep.Add(new ValidationExceptionItem("This email address is already registered, please use a different one."));
            }

            //check that the school name and town is unique
            tmp = School.GetBySchoolNameAndTown(SchoolName, Town, context);
            if (tmp != null && tmp.Id != this.Id)
            {
                valExcep.Add(new ValidationExceptionItem("This school has already been entered."));
            }

            if (valExcep.Items.Length > 0)
            {
                throw valExcep;
            }
        }

        public const string EmailValidationExpression = @"^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z+])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$";
        public static bool ValidateEmail(string emailAddress)
        {
            System.Text.RegularExpressions.Regex regEx = new System.Text.RegularExpressions.Regex(EmailValidationExpression);
            return regEx.IsMatch(emailAddress);
        }

        public const string PostCodeValidationExpression = @"^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) {0,1}[0-9][A-Za-z]{2})$";
        public static bool ValidatePostCode(string postCode)
        {
            System.Text.RegularExpressions.Regex regEx = new System.Text.RegularExpressions.Regex(PostCodeValidationExpression);
            return regEx.IsMatch(postCode);
        }

        public const string PasswordValidationExpression = @"^[A-Za-z0-9]{6,14}";
        public static bool ValidatePassword(string password)
        {
            System.Text.RegularExpressions.Regex regEx = new System.Text.RegularExpressions.Regex(PasswordValidationExpression);
            return regEx.IsMatch(password);
        }

        public static School GetBySchoolNameAndTown(string schoolName, string town, DataContext context)
        {
            var res = from s in context.Schools
                      where s.SchoolName == schoolName && s.Town == town
                      select s;
            return res.FirstOrDefault();
        }

        public static School GetByContactEmail(string email, DataContext context)
        {
            var res = from s in context.Schools
                      where s.ContactEmail == email
                      select s;
            return res.FirstOrDefault();
        }

        public static School GetById(int id, DataContext context)
        {
            var res = from s in context.Schools
                      where s.Id == id
                      select s;
            return res.FirstOrDefault();
        }*/
    }
}
